/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package ace.game.entity.player;

import ace.game.entity.body.BodyFactory;
import ace.game.entity.weapon.Weapon;
import ace.game.entity.weapon.WeaponFactory;
import ace.system.Model;
import ace.system.Utilities;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

/**
 *
 * @author Hallucinogen
 */
public class Profile extends Model {
    public Profile(String name, int hashIndex) {
		if(name == null)	mName	= "Default";
		else				mName	= name;
		mLevel			= 1;
        mSaveIndex      = hashIndex;

        mUsedBody       = 1;
        mUsedWeapon     = new int[]{1, -1, -1, -1, -1, -1};
        mBuyableBody    = new boolean[10];
        mBuyableWeapon  = new boolean[40];
        mBoughtBody     = new boolean[10];
        mBoughtWeapon   = new boolean[40];

        // let some of few first bodies be buyable
        for (int i = 1; i < 3; ++i) {
            mBuyableBody[i]     = true;
        }
        // let some of few first weapons be buyable
        for (int i = 1; i <= 7; ++i) {
            mBuyableWeapon[i]   = true;
        }
        mBoughtBody[1]      = true;
        mBoughtWeapon[1]    = true;

        mMoney              = 12000;
    }

	public Profile(){
		this("Default", 0);
	}

	public Profile(byte[] data){
		fromByteArray(data);
	}

    public Player buildPlayer() {
        Player player = new Player(BodyFactory.instance().getBodyData(mUsedBody));
        for (int i = 0; i < mUsedWeapon.length; ++i) {
            if (mUsedWeapon[i] > -1) {
                player.addWeapon(new Weapon(WeaponFactory.instance().getWeaponData(mUsedWeapon[i])));
            }
        }
        return player;
    }

    public void addMoney(int money) {
        mMoney += money;
    }

    public void setUsedBody(int body) {
        mUsedBody = body;
    }

    // TODO: read from persitence data (RMS?)
	/* Usage example:
	 * Model.writeModel(1, new Profile()); 1 = recordID
	 * Profile p = new Profile(Model.getModelByteData(1)); 1 = recordID
	 * p.dumpModel();
	 */

    public String getProfileName()      {   return mName;               }
	public int getLevel()               {   return mLevel;              }
    public int getMoney()               {   return mMoney;              }
    public int getUsedBody()            {   return mUsedBody;           }
    public int getTotalMissionScore()   {   return mTotalMissionScore;  }
    public int getSaveIndex()           {   return mSaveIndex;         }
    public int[] getUsedWeapon()        {   return mUsedWeapon;         }
    public boolean[] getBuyableBody()   {   return mBuyableBody;        }
    public boolean[] getBuyableWeapon() {   return mBuyableWeapon;      }
    public boolean[] getBoughtBody()    {   return mBoughtBody;         }
    public boolean[] getBoughtWeapon()  {   return mBoughtWeapon;       }

    public void setHashIndex(int index) {   mSaveIndex = index;         }


    public void setLevel(int level)     {
        if (level <= Utilities.MAX_LEVEL) {
            mLevel = level;
        }
    }

    public int getAccomplishment()      {
        int boughtBody = 0, boughtWeapon = 0;
        for (int i = 0; i < mBoughtBody.length; ++i) {
            if (mBoughtBody[i])
                ++boughtBody;
        }
        for (int i = 0; i < mBoughtWeapon.length; ++i) {
            if (mBoughtWeapon[i])
                ++boughtWeapon;
        }
        return (boughtBody + boughtWeapon) * 100 / (mBoughtBody.length + mBoughtWeapon.length);
    }

    public void addTotalMissionScore(int value) {
        mTotalMissionScore += value;
    }

	public void dumpModel(){
		System.out.println("mName = " + mName);
		System.out.println("mUsedBody = " + mUsedBody);

		for(int i=0; i<mUsedWeapon.length; ++i){
			System.out.println("mUsedWeapon[" + i + "] = " + mUsedWeapon[i]);
		}

		for(int i=0; i<mBuyableBody.length; ++i){
			System.out.println("mBuyableBody[" + i + "] = " + mBuyableBody[i]);
		}

		for(int i=0; i<mBuyableWeapon.length; ++i){
			System.out.println("mBuyableWeapon[" + i + "] = " + mBuyableWeapon[i]);
		}
	}

    private String		mName;
	private int			mLevel;
    private int			mUsedBody;
    private int         mMoney;
    private int         mTotalMissionScore;

    // for RMS
    private int         mSaveIndex;
	
    // only 6 weapon max
    private int[]		mUsedWeapon;
    // if true then body of that index is buyable
    private boolean[]	mBuyableBody;
    // if true then weapon of that index is buyable
    private boolean[]	mBuyableWeapon;
    // if true then body already bought
    private boolean[]	mBoughtBody;
    // if true then weapon already bought
    private boolean[]	mBoughtWeapon;

	public void fromByteArray(byte[] data) {
		int ctr;
		ByteArrayInputStream bin = new ByteArrayInputStream(data);
		DataInputStream din = new DataInputStream(bin);
		
		try {
			mName		= din.readUTF();
			mLevel		= din.readInt();
			mUsedBody	= din.readInt();
			mSaveIndex	= din.readInt();

			//Reading mUsedWeapon
			ctr = din.readInt();
			mUsedWeapon = new int[ctr];
			for (int i = 0; i < ctr; ++i) {
				mUsedWeapon[i] = din.readInt();
			}

			//Reading mBuyableBody
			ctr = din.readInt();
			mBuyableBody = new boolean[ctr];
			for (int i = 0; i < ctr; ++i) {
				mBuyableBody[i] = din.readBoolean();
			}

			//Reading mBuyableWeapon
			ctr = din.readInt();
			mBuyableWeapon = new boolean[ctr];
			for (int i = 0; i < ctr; ++i) {
				mBuyableWeapon[i] = din.readBoolean();
			}

			//Reading mBoughtBody
			ctr = din.readInt();
			mBoughtBody = new boolean[ctr];
			for (int i = 0; i < ctr; ++i) {
				mBoughtBody[i] = din.readBoolean();
			}

			//Reading mBoughtWeapon
			ctr = din.readInt();
			mBoughtWeapon = new boolean[ctr];
			for (int i = 0; i < ctr; ++i) {
				mBoughtWeapon[i] = din.readBoolean();
			}
			
			din.close();
		} catch (IOException ex) {}
	}

	public byte[] toByteArray() {
		ByteArrayOutputStream bout = new ByteArrayOutputStream();
		DataOutputStream dout = new DataOutputStream(bout);
		
		try {
			dout.writeUTF(mName);
			dout.writeInt(mLevel);
			dout.writeInt(mUsedBody);
			dout.writeInt(mSaveIndex);

			//Writing mUsedWeapon
			dout.writeInt(mUsedWeapon.length);
			for (int i = 0; i < mUsedWeapon.length; ++i) {
				dout.writeInt(mUsedWeapon[i]);
			}

			//Writing mBuyableBody
			dout.writeInt(mBuyableBody.length);
			for (int i = 0; i < mBuyableBody.length; ++i) {
				dout.writeBoolean(mBuyableBody[i]);
			}

			//Writing mBuyableWeapon
			dout.writeInt(mBuyableWeapon.length);
			for (int i = 0; i < mBuyableWeapon.length; ++i) {
				dout.writeBoolean(mBuyableWeapon[i]);
			}

			//Writing mBoughtBody
			dout.writeInt(mBoughtBody.length);
			for (int i = 0; i < mBoughtBody.length; ++i) {
				dout.writeBoolean(mBoughtBody[i]);
			}

			//Writing mBoughtWeapon
			dout.writeInt(mBoughtWeapon.length);
			for (int i = 0; i < mBoughtWeapon.length; ++i) {
				dout.writeBoolean(mBoughtWeapon[i]);
			}
			
			dout.close();
		} catch (IOException ex) {}
		
		return bout.toByteArray();
	}
}
